home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / dday.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  12KB  |  482 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12. unsigned char *dday_videoram2;
  13. unsigned char *dday_videoram3;
  14. static int control = 0;
  15.  
  16. static unsigned char *searchlight_image;
  17. static int searchlight_flipx;
  18. static int searchlight_enable = 0;
  19.  
  20.  
  21. /* LBO */
  22. #ifdef LSB_FIRST
  23. #define BL0 0
  24. #define BL1 1
  25. #define BL2 2
  26. #define BL3 3
  27. #else
  28. #define BL0 3
  29. #define BL1 2
  30. #define BL2 1
  31. #define BL3 0
  32. #endif
  33.  
  34. #ifdef ALIGN_INTS /* GSL 980108 read/write nonaligned dword routine for ARM processor etc */
  35.  
  36. INLINE UINT32 read_dword(void *address)
  37. {
  38.     if ((long)address & 3)
  39.     {
  40.           return (*((UINT8 *)address+BL0) +
  41.                (*((UINT8 *)address+BL1) << 8)  +
  42.                (*((UINT8 *)address+BL2) << 16) +
  43.                (*((UINT8 *)address+BL3) << 24) );
  44.     }
  45.     else
  46.         return *(UINT32 *)address;
  47. }
  48.  
  49.  
  50. #else
  51. #define read_dword(address) *(UINT32 *)address
  52. #endif
  53.  
  54.  
  55. static void drawgfx_shadow(struct osd_bitmap *dest,const struct GfxElement *gfx,
  56.         unsigned int code,unsigned int color,int sx,int sy,
  57.         const struct rectangle *clip,int transparency,
  58.         UINT8* shadow_mask, UINT8* layer_mask, int layer)
  59. {
  60.     int ox,oy,ex,ey,y,start;
  61.     const UINT8 *sd;
  62.     UINT8 *bm,*bme;
  63.     UINT8 col;
  64.     int *sd4;
  65.     int col4;
  66.     int f,shadow=0,l;
  67.  
  68.  
  69.     code %= gfx->total_elements;
  70.     color %= gfx->total_colors;
  71.  
  72.  
  73.     /* check bounds */
  74.     ox = sx;
  75.     oy = sy;
  76.     ex = sx + gfx->width-1;
  77.     if (sx < 0) sx = 0;
  78.     if (clip && sx < clip->min_x) sx = clip->min_x;
  79.     if (ex >= dest->width) ex = dest->width-1;
  80.     if (clip && ex > clip->max_x) ex = clip->max_x;
  81.     if (sx > ex) return;
  82.     ey = sy + gfx->height-1;
  83.     if (sy < 0) sy = 0;
  84.     if (clip && sy < clip->min_y) sy = clip->min_y;
  85.     if (ey >= dest->height) ey = dest->height-1;
  86.     if (clip && ey > clip->max_y) ey = clip->max_y;
  87.     if (sy > ey) return;
  88.  
  89.     osd_mark_dirty (sx,sy,ex,ey,0);    /* ASG 971011 */
  90.  
  91.     start = code * gfx->height + (sy-oy);
  92.  
  93.     if (gfx->colortable)    /* remap colors */
  94.     {
  95.         const unsigned short *paldata;    /* ASG 980209 */
  96.  
  97.         paldata = &gfx->colortable[gfx->color_granularity * color];
  98.  
  99.         switch (transparency)
  100.         {
  101.         case TRANSPARENCY_NONE:
  102.             if (layer_mask)
  103.             {
  104.                 for (y = sy;y <= ey;y++)
  105.                 {
  106.                     bm  = dest->line[y];
  107.                     bme = bm + ex;
  108.                     sd = gfx->gfxdata + start * gfx->line_modulo + (sx-ox);
  109.                     for( bm += sx ; bm <= bme-7 ; bm+=8)
  110.                     {
  111.                         shadow = *(shadow_mask++);
  112.                         l = *(layer_mask++);
  113.  
  114.                         if (((l & 0x01) >> 0) == layer)  bm[0] = paldata[sd[0]+((shadow & 0x01) << 8)];
  115.                         if (((l & 0x02) >> 1) == layer)  bm[1] = paldata[sd[1]+((shadow & 0x02) << 7)];
  116.                         if (((l & 0x04) >> 2) == layer)  bm[2] = paldata[sd[2]+((shadow & 0x04) << 6)];
  117.                         if (((l & 0x08) >> 3) == layer)  bm[3] = paldata[sd[3]+((shadow & 0x08) << 5)];
  118.                         if (((l & 0x10) >> 4) == layer)  bm[4] = paldata[sd[4]+((shadow & 0x10) << 4)];
  119.                         if (((l & 0x20) >> 5) == layer)  bm[5] = paldata[sd[5]+((shadow & 0x20) << 3)];
  120.                         if (((l & 0x40) >> 6) == layer)  bm[6] = paldata[sd[6]+((shadow & 0x40) << 2)];
  121.                         if (((l & 0x80) >> 7) == layer)  bm[7] = paldata[sd[7]+((shadow & 0x80) << 1)];
  122.                         sd+=8;
  123.                     }
  124.                     start+=1;
  125.                 }
  126.             }
  127.             else
  128.             {
  129.                 for (y = sy;y <= ey;y++)
  130.                 {
  131.                     bm  = dest->line[y];
  132.                     bme = bm + ex;
  133.                     sd = gfx->gfxdata + start * gfx->line_modulo + (sx-ox);
  134.                     for( bm += sx ; bm <= bme-7 ; bm+=8)
  135.                     {
  136.                         shadow = *(shadow_mask++);
  137.  
  138.                         bm[0] = paldata[sd[0]+((shadow & 0x01) << 8)];
  139.                         bm[1] = paldata[sd[1]+((shadow & 0x02) << 7)];
  140.                         bm[2] = paldata[sd[2]+((shadow & 0x04) << 6)];
  141.                         bm[3] = paldata[sd[3]+((shadow & 0x08) << 5)];
  142.                         bm[4] = paldata[sd[4]+((shadow & 0x10) << 4)];
  143.                         bm[5] = paldata[sd[5]+((shadow & 0x20) << 3)];
  144.                         bm[6] = paldata[sd[6]+((shadow & 0x40) << 2)];
  145.                         bm[7] = paldata[sd[7]+((shadow & 0x80) << 1)];
  146.                         sd+=8;
  147.                     }
  148.                     start+=1;
  149.                 }
  150.             }
  151.             break;
  152.  
  153.         case TRANSPARENCY_PEN:
  154.  
  155.             for (y = sy;y <= ey;y++)
  156.             {
  157.                 bm  = dest->line[y];
  158.                 bme = bm + ex;
  159.                 sd4 = (int *)(gfx->gfxdata + start * gfx->line_modulo + (sx-ox));
  160.                 f = 0;
  161.                 for( bm += sx ; bm <= bme-3 ; bm+=4, f^=1 )
  162.                 {
  163.                     if (f)
  164.                     {
  165.                         shadow >>= 4;
  166.                     }
  167.                     else
  168.                     {
  169.                         shadow = *(shadow_mask++);
  170.                     }
  171.                     col4 = read_dword(sd4);
  172.                     if (col4)
  173.                     {
  174.                         col = col4;
  175.                         if (col)  bm[BL0] = paldata[col+((shadow & 0x01) << 8)];
  176.                         col = col4>>8;
  177.                         if (col)  bm[BL1] = paldata[col+((shadow & 0x02) << 7)];
  178.                         col = col4>>16;
  179.                         if (col)  bm[BL2] = paldata[col+((shadow & 0x04) << 6)];
  180.                         col = col4>>24;
  181.                         if (col)  bm[BL3] = paldata[col+((shadow & 0x08) << 5)];
  182.                     }
  183.                     sd4++;
  184.                 }
  185.                 start+=1;
  186.             }
  187.             break;
  188.         }
  189.     }
  190. }
  191.  
  192.  
  193. /***************************************************************************
  194.  
  195.   Convert the color PROMs into a more useable format.
  196.  
  197. ***************************************************************************/
  198. void dday_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  199. {
  200.     int i,total;
  201.  
  202.     total = Machine->drv->total_colors/2;
  203.  
  204.     for (i = 0;i < total;i++)
  205.     {
  206.         int bit0,bit1,bit2,bit3,r,g,b;
  207.  
  208.  
  209.         /* red component */
  210.         bit0 = (color_prom[0] >> 0) & 0x01;
  211.         bit1 = (color_prom[0] >> 1) & 0x01;
  212.         bit2 = (color_prom[0] >> 2) & 0x01;
  213.         bit3 = (color_prom[0] >> 3) & 0x01;
  214.         r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
  215.         /* green component */
  216.         bit0 = (color_prom[total] >> 0) & 0x01;
  217.         bit1 = (color_prom[total] >> 1) & 0x01;
  218.         bit2 = (color_prom[total] >> 2) & 0x01;
  219.         bit3 = (color_prom[total] >> 3) & 0x01;
  220.         g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
  221.         /* blue component */
  222.         bit0 = (color_prom[2*total] >> 0) & 0x01;
  223.         bit1 = (color_prom[2*total] >> 1) & 0x01;
  224.         bit2 = (color_prom[2*total] >> 2) & 0x01;
  225.         bit3 = (color_prom[2*total] >> 3) & 0x01;
  226.         b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
  227.  
  228.         palette[0] = r;
  229.         palette[1] = g;
  230.         palette[2] = b;
  231.  
  232.         /* darker version for searchlight */
  233.         palette[3*256  ] = r >> 3;
  234.         palette[3*256+1] = g >> 3;
  235.         palette[3*256+2] = b >> 3;
  236.  
  237.         palette += 3;
  238.  
  239.         color_prom++;
  240.     }
  241.  
  242.  
  243.     /* HACK!!! This table is handgenerated, but it matches the screenshot.
  244.        I have no clue how it really works */
  245.  
  246.     colortable[0*4+0] = 0;
  247.     colortable[0*4+1] = 1;
  248.     colortable[0*4+2] = 21;
  249.     colortable[0*4+3] = 2;
  250.  
  251.     colortable[1*4+0] = 4;
  252.     colortable[1*4+1] = 5;
  253.     colortable[1*4+2] = 3;
  254.     colortable[1*4+3] = 7;
  255.  
  256.     colortable[2*4+0] = 8;
  257.     colortable[2*4+1] = 21;
  258.     colortable[2*4+2] = 10;
  259.     colortable[2*4+3] = 3;
  260.  
  261.     colortable[3*4+0] = 8;
  262.     colortable[3*4+1] = 21;
  263.     colortable[3*4+2] = 10;
  264.     colortable[3*4+3] = 3;
  265.  
  266.     colortable[4*4+0] = 16;
  267.     colortable[4*4+1] = 17;
  268.     colortable[4*4+2] = 18;
  269.     colortable[4*4+3] = 7;
  270.  
  271.     colortable[5*4+0] = 29;
  272.     colortable[5*4+1] = 21;
  273.     colortable[5*4+2] = 22;
  274.     colortable[5*4+3] = 27;
  275.  
  276.     colortable[6*4+0] = 29;
  277.     colortable[6*4+1] = 21;
  278.     colortable[6*4+2] = 26;
  279.     colortable[6*4+3] = 27;
  280.  
  281.     colortable[7*4+0] = 29;
  282.     colortable[7*4+1] = 2;
  283.     colortable[7*4+2] = 4;
  284.     colortable[7*4+3] = 27;
  285.  
  286.     for (i = 0; i < 8*4; i++)
  287.     {
  288.         colortable[i+256] = colortable[i] + 256;
  289.     }
  290. }
  291.  
  292.  
  293. void dday_decode(void)
  294. {
  295.     int i;
  296.     UINT8 *mask = memory_region(REGION_GFX4);
  297.     UINT8 data;
  298.  
  299.  
  300.     /* create x-flipped search light mask */
  301.     for (i = 0x1000; i < 0x1800; i++)
  302.     {
  303.         data = mask[i];
  304.  
  305.         mask[i + 0x800] = ((data >> 7) & 0x01) | ((data >> 5) & 0x02) |
  306.                            ((data >> 3) & 0x04) | ((data >> 1) & 0x08) |
  307.                           ((data << 1) & 0x10) | ((data << 3) & 0x20) |
  308.                           ((data << 5) & 0x40) | ((data << 7) & 0x80);
  309.     }
  310. }
  311.  
  312.  
  313. WRITE_HANDLER( dday_colorram_w )
  314. {
  315.     colorram[offset & 0x3e0] = data;
  316. }
  317.  
  318. READ_HANDLER( dday_colorram_r )
  319. {
  320.     return colorram[offset & 0x3e0];
  321. }
  322.  
  323. WRITE_HANDLER( dday_searchlight_w )
  324. {
  325.     searchlight_image = &memory_region(REGION_GFX4)[0x200*(data & 0x07)];
  326.     searchlight_flipx = (data >> 3) & 0x01;
  327. }
  328.  
  329. WRITE_HANDLER( dday_control_w )
  330. {
  331.     //logerror("Control = %02X\n", data);
  332.  
  333.     /* Bit 0 is coin counter 1 */
  334.     coin_counter_w(0, data & 0x01);
  335.  
  336.     /* Bit 1 is coin counter 2 */
  337.     coin_counter_w(1, data & 0x02);
  338.  
  339.     /* Bit 4 is sound enable */
  340.     if (!(data & 0x10) && (control & 0x10))
  341.     {
  342.         AY8910_reset(0);
  343.         AY8910_reset(1);
  344.     }
  345.  
  346.     mixer_sound_enable_global_w(data & 0x10);
  347.  
  348.     /* Bit 6 is search light enable */
  349.     searchlight_enable = data & 0x40;
  350.  
  351.     control = data;
  352. }
  353.  
  354. /***************************************************************************
  355.  
  356.   Draw the game screen in the given osd_bitmap.
  357.   Do NOT call osd_update_display() from this function, it will be called by
  358.   the main emulation engine.
  359.  
  360. ***************************************************************************/
  361. void dday_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  362. {
  363.     int offs;
  364.  
  365.  
  366.     for (offs = videoram_size - 1;offs >= 0;offs--)
  367.     {
  368.         int code, code_background, sx, sy, flipx;
  369.         UINT8* searchlight_bitmap;
  370.  
  371.  
  372.         sy = (offs / 32);
  373.         sx = (offs % 32);
  374.  
  375.         flipx = 0;
  376.         code = 0;
  377.  
  378.         /* draw the search light, if enabled */
  379.         if (searchlight_enable)
  380.         {
  381.             flipx = (sx >> 4) & 0x01;
  382.             code = searchlight_image[(sy << 4) | (flipx ? sx ^ 0x1f: sx)];
  383.  
  384.             if (searchlight_flipx != flipx)
  385.             {
  386.                 if (code & 0x80)
  387.                 {
  388.                     /* No mirroring, draw dark spot */
  389.                     code = 1;
  390.                 }
  391.             }
  392.  
  393.             code &= 0x3f;
  394.         }
  395.  
  396.         searchlight_bitmap = &memory_region(REGION_GFX4)[(flipx ? 0x1800 : 0x1000) | (code << 3)];
  397.  
  398.         sx *= 8;
  399.         sy *= 8;
  400.  
  401.  
  402.         code_background = videoram[offs];
  403.  
  404.         flipx  = colorram[sy << 2] & 0x01;
  405.         code = dday_videoram3[flipx ? offs ^ 0x1f : offs];
  406.  
  407.         /* is the vehicle layer character non-blank? */
  408.         if (code)
  409.         {
  410.             UINT8* layer_bitmap;
  411.  
  412.  
  413.             layer_bitmap = &memory_region(REGION_GFX5)[code_background << 3];
  414.  
  415.             /* draw part of background appearing behind the vehicles
  416.                skipping characters totally in the foreground */
  417.             if (layer_bitmap[0] || layer_bitmap[1] || layer_bitmap[2] || layer_bitmap[3] ||
  418.                 layer_bitmap[4] || layer_bitmap[5] || layer_bitmap[6] || layer_bitmap[7])
  419.             {
  420.                 drawgfx_shadow(bitmap,Machine->gfx[0],
  421.                                code_background,
  422.                                code_background >> 5,
  423.                                sx,sy,
  424.                                &Machine->drv->visible_area,TRANSPARENCY_NONE,
  425.                                searchlight_bitmap,
  426.                                layer_bitmap, 1);
  427.             }
  428.  
  429.  
  430.             /* draw vehicles */
  431.             drawgfx_shadow(bitmap,Machine->gfx[flipx ? 3 : 2],
  432.                            code,
  433.                            code >> 5,
  434.                            sx,sy,
  435.                            &Machine->drv->visible_area,TRANSPARENCY_PEN,
  436.                            searchlight_bitmap,
  437.                            0, 0);
  438.  
  439.  
  440.             /* draw part of background appearing in front of the vehicles
  441.                skipping characters totally in the background */
  442.             if (~layer_bitmap[0] || ~layer_bitmap[1] || ~layer_bitmap[2] || ~layer_bitmap[3] ||
  443.                 ~layer_bitmap[4] || ~layer_bitmap[5] || ~layer_bitmap[6] || ~layer_bitmap[7])
  444.             {
  445.                 drawgfx_shadow(bitmap,Machine->gfx[0],
  446.                                code_background,
  447.                                code_background >> 5,
  448.                                sx,sy,
  449.                                &Machine->drv->visible_area,TRANSPARENCY_NONE,
  450.                                searchlight_bitmap,
  451.                                layer_bitmap, 0);
  452.             }
  453.         }
  454.         else
  455.         {
  456.             /* draw background, we don't have to worry about the layering */
  457.             drawgfx_shadow(bitmap,Machine->gfx[0],
  458.                            code_background,
  459.                            code_background >> 5,
  460.                            sx,sy,
  461.                            &Machine->drv->visible_area,TRANSPARENCY_NONE,
  462.                            searchlight_bitmap,
  463.                            0, 0);
  464.         }
  465.  
  466.  
  467.         /* draw text layer */
  468.         code = dday_videoram2[offs];
  469.  
  470.         if (code)
  471.         {
  472.             drawgfx_shadow(bitmap,Machine->gfx[1],
  473.                            code,
  474.                            code >> 5,
  475.                            sx,sy,
  476.                            &Machine->drv->visible_area,TRANSPARENCY_PEN,
  477.                            searchlight_bitmap,
  478.                            0, 0);
  479.         }
  480.     }
  481. }
  482.